# 元组与列表类似 但是元组中的元素不能修改 同时定义使用的是()
# t1 = (1,2,3,4,5)
# t2 = ('张三','李四','王五')
# t3 = (100,True,'张三',None)
# t4 = (1,2,4,[1,3,5])
# # print(t1)
# # print(t2)
# # print(t3)
# # print(t4)
# #
# # # 通过下标取值
# # print(t1[0])
# # print(t1[-1])
# # print(t4[3][1])
#
# # 元组中如果存放了可变类型(列表) 那么可变类型中的内容是可以修改的
# # 不管嵌套多深 如果数据本身时可以修改的 就可以修改 例如列表中的元素
# # 如果元组中存放的是不可变类型(字符串,元组,数字,布尔值) 那么元组中的内容是不能修改的
# t4[3][1] = 100
# print(t4)
from time import process_time_ns

from win32print import PRINTER_ENUM_NETWORK

# from reportlab.platypus.paragraph import strip

# 定义空元组
# t1 = ()
# t2 = tuple()
# print(t1,t2,type(t1),type(t2))
# # 定义只有一个元素的元组 注意：如果只有一个元素的元组 那么必须在元素后面添加一个逗号
# #
# t3 =(100,)
# print(type(t3))
# t4 = ('张三',) # 如果不加逗号 python会以为这是一个字符串 后面那个括号就多余了
# print(t4,type(t4))
# t5 = (
#     '中华'
#     '人民共和国' # 这时候不需要写逗号 因为这里是一个字符串 python会拼接到一起
# )
# print(t5,type(t5)) # 字符串
#
# # 元组的常用方法
# # 元组中如果只有一个元素 如果没有加逗号 python会认为是一个字符串,如果是数字就是int类型
# # 即一个元素且不加逗号时，数据类型为原本的数据类型 而不是元组
# t1 = (1,3,5,7,9,3)
# print(t1.index(3)) # 查看元素在元组中的下标
# print(t1.count(3)) # 查看元素在元组中出现的次数


# 元组常用的内置函数
# t1 =(1,3,5,7,9)
# print(max(t1))
# print(min(t1))
# print(len(t1))
# print(sorted(t1)) #排序 升序   sorted函数返回类型为列表
# print(sorted(t1,reverse=True)) # 降序
# print(sum(t1))
#
# # 如果想要sorted()排序后的结果为元组 就需要使用tuple函数来将其转换为元组
# result = sorted(t1)
# print(tuple(result))

# 实际开发的元组 可能不是我们定义 比如函数的可变参数*args
# def func(*args):
#         print(sum(args))
# func(1,2,3)

# 元组的遍历
# t1 = (1,3,5,7,9)
# for item in t1:
#     print(item)



# 字符串
# 字符串中的字符不可以修改
# 字符串不可以嵌套 例如 [1,2,3,[1,2,3]] (1,2,3,(1,2,3))
# msg = 'welcome to shanghai'
# print(msg[0])
#
# # 字符串常用方法
# # 1.idnex 获取指定字符在字符串中第一次出现的下标
# print(msg.index('l')) # 2
# 2.split方法 将字符串按照指定字符进行分隔 并返回一个列表
# msg = 'hello@@你好@@中国'
# result = msg.split('@')
# print(result)
# # 3.replace方法 将字符串中某个字符串片段 替换为目标字符串
# msg2 = 'hello python world'
# result2 = msg2.replace('h','H')
# print(result2)
# # count 统计指定字符在字符串中出现的次数
# print(msg2.count('o')) # 3

# strip方法 从字符串两端开始删除 直到遇到了第一个不在指定字符串中的字符就停下
# msg3 = '66你6真6好666'
# result3 = msg3.strip('6')
# print(result3) # 你6真6好

# 不改变原字符串  而是生成一个新的字符串
# msg4 = '1234567123你1243好1264321'
# result4 = msg4.strip('1324') #只要连续的包含1324中的任意一个字符 就会被删除掉
# print(result4) #
#
# print(len(msg4)) # 求长度
# for item in msg4:
#     print(item,end=' ')

# 序列的切片操作
# 序列：能连续存放元素的数据容器 元素有先后顺序 且可以通过下标访问
# 常见序列有 列表 元组 字符串
# 切片： 从序列中按照指定范围 去除一部分元素 形成一个新的序列的操作
# 序列[起始索引:结束索引:步长]
# 不改变原序列 生成新的序列
# msg = 'hello world python'
# print(msg[5:12:1]) # 最终切片中不包含结束索引的元素 但是包含起始索引
# list1 = [10,20,30,40,50,60,70,80,90,100]
# print(list1[2:6:1]) # 30 40 50 60
# print(list1[::2]) # 10 30 50 70 90
#
# # 注意：当起始索引大于 结束索引时 步长必须为负数 否则结果是空列表
# print(list1[7:2:-1]) # 80 70 60 50 40
# # 特殊情况 当同时省略起始索引和结束索引时 如果步长是负数
# # 那么python会自动对调起始位置和节数位置
# print(list1[::-1]) # 100 90 80 70 60 50 40 30 20 10

# 序列的相加和相乘
# 1.相加：只有同类型的序列才可以相加(字符串+字符串，列表+列表，元组+元组)
# list1 = [1,2,3,4,5]
# list2 = [6,7,8,9,10]
# list3 = list1+list2
# print(list3) # 12345678910
#
# tuple1 = (1,2,3,4,5)
# tuple2 = (6,7,8,9,10)
# tuple3 =tuple1+tuple2
# print(tuple3)
#
# str1 = 'hello'
# str2 = 'world'
# str3 =str1+str2
# print(str3)
#
# # 序列的相乘（重复）
# # 新序列等于旧序列 * n （n必须是整数 不能是浮点数）
# list4 = list3 * 2
# print(list4)
#
# tuple4 = tuple3 *2
# print(tuple4)
#
# str4 = str3*3
# print(str4)


# 数据容器：集合
# 可变集合(set):创建后可以增删元素 和不可变集合(frozenset)：创建后不可以增删元素
# 集合内部的元素是无序的 不能通过下标来访问元素 会自动去除重复的元素

# s1 = {1,2,3,4,5,6,78,12,45,4,8,7,8} # 无序的 同时删除了重复的元素
# s2 = {'hello','你好','python'}
#
# print(s1,type(s1))
# print(s2,type(s2))
# print(s3,type(s3))  # True和1会有一个被去重

# 不可变集合
# s1 = frozenset({1,2,3,4,5,6,78,12,45,4,8,7,8})
# s2 = frozenset({'hello','你好','python'})
# s3 = frozenset({10,'hello',1,'你好',True,1,12.4})
# print(s1,type(s1))
# print(s2,type(s2))
# print(s3,type(s3))
#
# # frozenset接受的参数可以是任意可迭代对象 但最终返回的一定是不可变集合
# str1 = frozenset('hello')
# print(str1,type(str1))

# 定义空集合
# s1 = set()
# s2 = {} # 这是一个空字典
# # 定义不可变空集合
# s3 =frozenset({})
# print(s1,type(s1))
# print(s2,type(s2))
# print(s3,type(s3))


# 集合中不能嵌套可变集合 只能嵌套不可变集合
# 只有不可变的东西才可以安全的放在集合里
# 原因：集合不支持下标 但是底层依然需要给其中的元素分配一个"编号"
# 这个编号可以快速定位元素 并且这个编号是哈希值
# 哈希值是通过内容计算出来的
# 内容一旦发生变化 哈希值就会变化 对于集合来说 元素的哈希值发生变化
# 就不能再通过原来的哈希值找到这个元素
# s1 = {1,2,3,4,5}  # 可变的集合
# s2 = frozenset({6,7,8,9,10}) # 不可变集合
# l1 = [100,200,300] # 列表 可变
# t1 = ('hello','world','你好') # 元组 不可变
#
# # s3 = {11,22,33,s1} # s1是可变的 不能嵌套在集合中
# s4 = {11,22,33,s2} # s2是不可变的 可以嵌套
# # s5 = {11,22,33,l1} # l1 是可变的 不能嵌套
# s6 = {11,22,33,t1} # t1是不可变的 可以嵌套
#
# print(s4,type(s4))
# print(s6,type(s6))

# 集合的增删改查
# s1= {1,2,3}
# s1.add(40)
# print(s1)
# # update方法 向集合中添加元素 必须传递可迭代对象 例如 列表 元组 集合
# s1.update([1,3,5,7,9]) # 列表
# s1.update({100,200}) # 集合
# s1.update((300,500)) # 元组
# s1.update(range(500,505))
# print(s1)

# 集合删除
# .remove(元素) 移除指定元素 如果不存在就报错
# .discard(元素) 移除指定元素 不存在也不报错
# .pop() 从集合中移除任意一个元素 返回值是移除的那个元素
# .clear() 清空集合
# s1 = {10,20,30,40,50}
# s1.remove(20)
# # s1.remove(22) # 报错因为22不存在
# print(s1)
# s1.discard(22)
# s1.discard(33) # 不报错
# print(s1)
# result = s1.pop() # 删除任意一个元素并返回
# print(result)
# print(s1)
# s1.clear() #删除所有元素
# print(s1)

# 集合修改
# 没有直接的修改方法 需要使用.remove() 加add()
# s1 = {1,2,3,4,5}
# s1.remove(3)
# s1.add(6)
# print(s1)
# # 集合查询：使用成员运算符
# result = 5 in s1 # 因为5在s1中 所以是 True
# print(result)
# result2 =  20 not in s1 # 因为20不在集合s1中 所以为True
# print(result2)


# 集合常用方法
# 集合A.difference(集合B)
# 用于找出集合a中不同于集合b的元素 返回一个新的集合
# s1 = {1,3,5,7,9}
# s2 = {1,2,5,4,8}
# result = s1.difference(s2)
# print(result) # 3 7 9
# # A.difference_update(B) 从集合A中删除集合B中存在的元素 集合A会被修改 集合B不会
# s1.difference_update(s2)  # 删除了1 5 打印结果为 3 7 9
# print(s1)
# # 集合A.union(集合B) 合并两个集合 返回一个新集合
# print(s1.union(s2)) # 重复的元素会自动去重
#
# # 集合A.issubset(集合B)
# # 判断集合A是否为集合B的子集
# # 如果集合B中包含集合A中的所有元素 就返回 True 否则返回False
# s3 = {10,20,30}
# s4 = {10,20,30,40,50}
# print(s3.issubset(s4))
#
# # 集合A.issuperset(集合B)
# # 判断集合A是否是集合B的超集
# # 如果集合A中包含了集合B中所有元素 返回True 否则返回False
# print(s4.issuperset(s3))
#
# # 集合A.isdisjoint(集合B)
# # 判断集合A和集合B是否没有交集
# # 如果没有交集 就返回True 只要有一个 公共元素 就返回False
# print(s3.isdisjoint(s4))


# 集合的运算 并集 交集 差集 对称差集
# s1 = {10,20,30,40,50}
# s2 = {10,30,50,60,70,90}
# print(s1 | s2) # 属于a或者属于b的
# print(s1 & s2) # 交集 a和b都有的元素
# print(s1-s2) # 差集 属于s1集合但是不属于s2集合的数据
# print(s1^s2)# 对称差集 找到属于s1集合或者属于s2集合 但是又不能同时属于他们两个的元素

# 集合的遍历
# s1 = {10,20,30,40,50,60,70,80}
# for item in s1:
#     print(item,end=' ') # 无序的

# 字典 dict 键(key) 值(value)  字典中key不能重复 如果重复 后面写的会覆盖之前写的
# 字典中的键 是不可变类型 值是任意类型
# 例如 可以将元组作为字典中的键 但是不能将列表作为字典中的键
# d2 = {(1,2,3):123}
# d3 = {[1,2,3]:123} # 报错 因为列表是可变数据类型 不能作为字典中的键
# print(d2)
# # print(d3)
# d1 = {'张三':80,'李四':90,'王五':88}
# print(d1,type(d1))
# print(d1.keys())
# print(d1.values())


# 字典可以嵌套
# student_dict = {
#     # 键:{值}
#     24213001: {'name':'张三','age':18,'gender':'男'},
#     24213002: {'name': '李四', 'age': 20, 'gender': '女'},
#     24213003: {'name': '王五', 'age': 25, 'gender': '男'}
# }
# print(student_dict)

# 字典的增删改查
# 查询
# d1 = {'张三':188,'李四':178,'王五':176}
# # 直接取值 如果键不存在 会直接报错
# result1 = d1['张三']
# # result2 = d1['赵六'] # 因为不存在 所以报错
# print(result1)
# # print(result2)
# # 安全取值 如果键不存在 则返回默认值（如果没有设置默认值 则会返回None）
# res=d1.get('赵六','抱歉 key不存在') # 后面为默认值
# print(res)


# 新增
# d1 = {'张三':18,'李四':20}
# d1['王五']=25
# print(d1)
#
# # 修改和新增写法一样 如果字典中有对应的key 就是修改 如果没有 就是新增
# d1['张三'] = 100
# print(d1)
# # 批量修改
# d1.update({'张三':500,'李四':550})
# print(d1)
#
# # 删除
# # 删除指定key所对应的那组键值对
# # del d1['张三']
# # print(d1)
#
# # result = d1.pop('张三')
# # print(d1)
# # print(result) # 返回的是key对应的value
#
# # pop方法可以设置默认值
# # 默认值可以保证 要删除的key不存在的情况下 程序不会报错 并且返回这个默认值
# result = d1.pop('赵六','删除失败!')
# print(result)
# print(d1)
#
# # 清空字典
# d1.clear()
# print(d1)

# 字典的常用方法
#keys方法：获取字典中所有的键 返回值是dict_keys 与列表类似 可以被遍历 但是不能通过下标访问元素
# d1= {'张三':188,'李四':178}
# result = d1.keys()
# # print(result,type(result))
# for item in result:
#     print(item)
#
# # 借助内置的list函数 可以将dict_keys转换为list
# # l1=list(result)
# # print(l1)
# # print(type(l1))
#
# # values方法 获取字典的所有的值 跟keys一样
# res = d1.values()
# print(res)
#
# # item方法:获取字典的所有的键值对
# # 获取字典中所有的键值对 每组键值对以元组的形式呈现
# # 返回类型是dist_items 特点与列表一样
# res2 = d1.items()
# print(res2,type(res2))


# 字典不能使用while循环遍历 但是可以使用for循环遍历
d1 = {'zhangsan':18,'lisi':20,'wangwu':25}
for key in d1:
    print(key,d1[key])

for key in d1.keys():
    print(key,d1[key])

























































